package com.jy.rhin.infra.repo.notfication.publish;

import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jy.common.UIDWorker;
import com.jy.framework.base.utils.DateUtil;
import com.jy.rhin.domain.notification.publish.PublishMessageDao;
import com.jy.rhin.domain.notification.publish.entity.PublishMessageDO;
import com.jy.rhin.domain.notification.publish.entity.PublishMessageStatisticsDO;
import com.jy.rhin.infra.repo.notfication.publish.mapper.PublishMessageFailMapper;
import com.jy.rhin.infra.repo.notfication.publish.mapper.PublishMessageMapper;
import com.jy.rhin.infra.repo.notfication.publish.mapper.PublishMessageStatisticsMapper;
import com.jy.rhin.infra.repo.notfication.publish.po.PublishMessageFailPO;
import com.jy.rhin.infra.repo.notfication.publish.po.PublishMessagePO;
import com.jy.rhin.infra.repo.notfication.publish.po.PublishMessageStatisticsPO;
import com.jy.rhin.infra.repo.notfication.topic.po.TopicQueryPO;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author WeiQ
 * @date 2022/6/29 17:07
 */
@Slf4j
@Component
public class PublishMessageDaoImpl implements PublishMessageDao {
    protected Log mpLog = LogFactory.getLog(getClass());

    @Resource
    UIDWorker uidWorker;
    @Resource
    PublishMessageMapper publishMessageMapper;
    @Resource
    PublishMessageFailMapper publishMessageFailMapper;
    @Resource
    PublishMessageStatisticsMapper publishMessageStatisticsMapper;


    @Override
    public void save(List<PublishMessageDO> records) {
        List<PublishMessagePO> poList = records.stream().map(publishMessageDO -> {
            PublishMessagePO po = new PublishMessagePO(publishMessageDO);
            long id = uidWorker.nextId();
            po.setId(id);
            publishMessageDO.setId(id);
            return po;
        }).collect(Collectors.toList());
        SqlHelper.executeBatch(TopicQueryPO.class, mpLog, poList, 100, (sqlSession, entity) -> sqlSession.insert(SqlHelper.getSqlStatement(PublishMessageMapper.class, SqlMethod.INSERT_ONE), entity));

    }

    /**
     * 保存发布消息记录 发送失败时，需要保存补偿记录
     *
     * @param publishMessage
     */
    @Override
    public void save(PublishMessageDO publishMessage) {
        publishMessageMapper.updateById(new PublishMessagePO(publishMessage));
        if (!Boolean.TRUE.equals(publishMessage.getResult())) {
            PublishMessageFailPO po = new PublishMessageFailPO();
            po.setId(uidWorker.nextId());
            po.setNotifyLogId(publishMessage.getId());
            po.setSuccess(publishMessage.getResult());
            po.setNotifyTime(publishMessage.getNotifyTime());
            po.setFailDesc(publishMessage.getResultDesc());
            po.setCreateTime(new Date());
            publishMessageFailMapper.insert(po);
        }
    }

    @Override
    public PublishMessageDO queryById(Long subscribeId) {
        PublishMessagePO po = publishMessageMapper.selectById(subscribeId);
        return Objects.isNull(po) ? null : po.toDO();
    }

    /**
     * 重置对应时间段的消息发送统计
     *
     * @param startDate
     * @param endDate
     */
    @Override
    public void resetStatistics(Date startDate, Date endDate) {
        publishMessageStatisticsMapper.deleteStatistics(startDate, endDate);
        Date endAddDate = DateUtil.dateAddDays(endDate, 1);
        publishMessageStatisticsMapper.insertStatistics(startDate, endAddDate);
    }

    /**
     * 保存消息发送统计
     *
     * @param publishMessageStatisticsDO
     */
    @Override
    public void saveStatistics(PublishMessageStatisticsDO publishMessageStatisticsDO) {
        PublishMessageStatisticsPO po = new PublishMessageStatisticsPO(publishMessageStatisticsDO);
        Integer count = publishMessageStatisticsMapper.countByNotifyDate(po.getNotifyDate());
        if (count == 0) {
            long id = uidWorker.nextId();
            po.setId(id);
            publishMessageStatisticsMapper.insert(po);
        } else {
            publishMessageStatisticsMapper.updateTotalByNotifyDate(po.getTotal(), po.getNotifyDate());
        }

    }
}
